package com.easylive.service.impl;

import java.beans.Transient;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;

import com.easylive.component.RedisComponent;
import com.easylive.entity.constants.Constants;
import org.springframework.stereotype.Service;

import com.easylive.entity.enums.PageSize;
import com.easylive.entity.query.CategoryInfoQuery;
import com.easylive.entity.po.CategoryInfo;
import com.easylive.entity.vo.PaginationResultVO;
import com.easylive.entity.query.SimplePage;
import com.easylive.mappers.CategoryInfoMapper;
import com.easylive.service.CategoryInfoService;
import com.easylive.utils.StringTools;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import static org.springframework.transaction.TransactionDefinition.ISOLATION_READ_COMMITTED;


/**
 * 分类信息 业务接口实现
 */
@Service("categoryInfoService")
public class CategoryInfoServiceImpl implements CategoryInfoService {

    @Resource
    private CategoryInfoMapper<CategoryInfo, CategoryInfoQuery> categoryInfoMapper;

    @Resource
    private RedisComponent redisComponent;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<CategoryInfo> findListByParam(CategoryInfoQuery param) {
        List<CategoryInfo> categoryInfos = this.categoryInfoMapper.selectList(param);
        if (param.getConvert2Tree() != null && param.getConvert2Tree()) {
            categoryInfos = convertLine2Tree(categoryInfos, Constants.ZERO);
        }
        return categoryInfos;
    }

    private List<CategoryInfo> convertLine2Tree(List<CategoryInfo> categoryInfos, Integer pid) {
        List<CategoryInfo> children = new ArrayList<>();
        for (CategoryInfo categoryInfo : categoryInfos) {
            if (categoryInfo.getpCategoryId() != null && categoryInfo.getpCategoryId() != null && pid.equals(categoryInfo.getpCategoryId())) {
                categoryInfo.setChildren(convertLine2Tree(categoryInfos, categoryInfo.getCategoryId()));
                children.add(categoryInfo);
            }
        }
        return children;
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(CategoryInfoQuery param) {
        return this.categoryInfoMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<CategoryInfo> findListByPage(CategoryInfoQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<CategoryInfo> list = this.findListByParam(param);
        PaginationResultVO<CategoryInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(CategoryInfo bean) {
        return this.categoryInfoMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<CategoryInfo> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.categoryInfoMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<CategoryInfo> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.categoryInfoMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Integer updateByParam(CategoryInfo bean, CategoryInfoQuery param) {
        StringTools.checkParam(param);
        return this.categoryInfoMapper.updateByParam(bean, param);
    }

    /**
     * 多条件删除
     */
    @Override
    public Integer deleteByParam(CategoryInfoQuery param) {
        StringTools.checkParam(param);
        return this.categoryInfoMapper.deleteByParam(param);
    }

    /**
     * 根据CategoryId获取对象
     */
    @Override
    public CategoryInfo getCategoryInfoByCategoryId(Integer categoryId) {
        return this.categoryInfoMapper.selectByCategoryId(categoryId);
    }

    /**
     * 根据CategoryId修改
     */
    @Override
    public Integer updateCategoryInfoByCategoryId(CategoryInfo bean, Integer categoryId) {
        return this.categoryInfoMapper.updateByCategoryId(bean, categoryId);
    }

    /**
     * 根据CategoryId删除
     */
    @Override
    public Integer deleteCategoryInfoByCategoryId(Integer categoryId) {
        return this.categoryInfoMapper.deleteByCategoryId(categoryId);
    }

    /**
     * 根据CategoryCode获取对象
     */
    @Override
    public CategoryInfo getCategoryInfoByCategoryCode(String categoryCode) {
        return this.categoryInfoMapper.selectByCategoryCode(categoryCode);
    }

    /**
     * 根据CategoryCode修改
     */
    @Override
    public Integer updateCategoryInfoByCategoryCode(CategoryInfo bean, String categoryCode) {
        return this.categoryInfoMapper.updateByCategoryCode(bean, categoryCode);
    }

    /**
     * 根据CategoryCode删除
     */
    @Override
    public Integer deleteCategoryInfoByCategoryCode(String categoryCode) {
        return this.categoryInfoMapper.deleteByCategoryCode(categoryCode);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW)
    @Override
    public void saveCategory(CategoryInfo categoryInfo) {
        CategoryInfo deBean = this.categoryInfoMapper.selectByCategoryCode(categoryInfo.getCategoryCode());
        // 新增时判断分类编码是否存在
        if (deBean != null && categoryInfo.getCategoryId() == null) {
            throw new RuntimeException("分类编码已存在");
        }
        // 修改时判断分类编码是否存在  如果deBean.getpCategoryId().equals(categoryInfo.getpCategoryId()) 为真，说明修改的就是自己这个，没问题
        if (deBean != null && categoryInfo.getCategoryId() != null && !deBean.getpCategoryId().equals(categoryInfo.getpCategoryId())) {
            throw new RuntimeException("分类编码已被其他分类使用");
        }
        //新增
        if (null == categoryInfo.getCategoryId()) {
            Integer maxSort = this.categoryInfoMapper.selectMaxSort(categoryInfo.getpCategoryId());
            categoryInfo.setSort(maxSort == null ? 0 : maxSort + 1);
            this.categoryInfoMapper.insert(categoryInfo);
        } else {
            this.categoryInfoMapper.updateByCategoryId(categoryInfo, categoryInfo.getCategoryId());
        }
        save2Redis();
    }

    @Override
    public void delCategory(Integer categoryId) {
        //TODO 查询分类下是否有视频

        CategoryInfoQuery categoryInfoQuery = new CategoryInfoQuery();
        categoryInfoQuery.setCategoryIdOrPCategoryId(categoryId);

        this.categoryInfoMapper.deleteByParam(categoryInfoQuery);

        // 刷新缓存
        save2Redis();

    }

    @Override
    public void changeSort(Integer pCategoryId, String categoryIds) {
        String[] split = categoryIds.split(",");
        List<CategoryInfo> categoryInfos = new ArrayList<>();
        Integer sort = 0;
        for (String categoryId : split) {
            CategoryInfo categoryInfo = new CategoryInfo();
            categoryInfo.setCategoryId(Integer.parseInt(categoryId));
            categoryInfo.setpCategoryId(pCategoryId);
            categoryInfo.setSort(++sort);
            categoryInfos.add(categoryInfo);
        }
        categoryInfoMapper.updateSortBatch(categoryInfos);

        // 刷新缓存
        save2Redis();

    }

    private void save2Redis() {
        CategoryInfoQuery query = new CategoryInfoQuery();
        query.setOrderBy("sort asc");
        query.setConvert2Tree(true);
        List<CategoryInfo> list = findListByParam(query);
        redisComponent.saveCategoryList(list);
    }

    @Override
    public List<CategoryInfo> getAllCategoryList() {
        List<CategoryInfo> categoryList = redisComponent.getCategoryList();
        if(categoryList.isEmpty()) {
            save2Redis();
        }
        return redisComponent.getCategoryList();
    }
}